import {
  FilterOperateEnum,
  type FilterGroup,
  type FormSchema,
  type PageCondition,
  type Rule,
  type SortCondition,
  type SortEnum,
  type Group,
  type PageRequest,
  type ComponentType,
} from "@/typings/dynamic-search";
import { notEmpty } from "@/util";

type comEventType = (schema: FormSchema) => void;

export const useSearch = () => {
  const sortConditions: SortCondition[] = [];
  const pageCondition: PageCondition = {
    pageIndex: 1,
    pageSize: 10,
    sortConditions: [],
  };
  const filterRules: Rule[] = [];
  const groups: Group[] = [];
  const filterGroup: FilterGroup = { rules: [], groups: [] };
  const searchCondition: PageRequest = { filterGroup: filterGroup, pageCondition: pageCondition };

  const commonComEvent = (schema: FormSchema) => {
    if (!notEmpty(schema.value)) return;
    const { code, value, operate, extraCode, extraOp } = schema;
    // 同一个value对应两个不同的查询条件
    if (schema.isGroup) {
      const rules: Rule[] = [genRule(code, value, operate), genRule(extraCode!, value, operate)];
      genGroup(rules, extraOp!);
    } else {
      filterRules.push(genRule(code, value, operate));
    }
  };

  /** 输入框 */
  const inputEvent = (schema: FormSchema) => {
    commonComEvent(schema);
  };

  /** 选择框 */
  const selectEvent = (schema: FormSchema) => {
    commonComEvent(schema);
  };

  /** 时间选择器,暂时只考虑 date datetime daterange naiveUI 提供了多种组件后续使用自行扩展 */
  const datePickerEvent = (schema: FormSchema) => {
    if (!notEmpty(schema.value)) return;

    const { code, value, operate, extraOp, datePickerType } = schema;

    if (["date", "datetime"].includes(datePickerType!)) {
      commonComEvent(schema);
    } else if (datePickerType === "daterange") {
      const rules: Rule[] = [
        genRule(code, value[0], operate || FilterOperateEnum.GREATER_THAN_EQUAL_TO),
        genRule(code, value[1], extraOp || FilterOperateEnum.LESS_THAN),
      ];
      filterRules.push(...rules);
    }
  };

  const comEventMap: Record<ComponentType, comEventType> = {
    Input: inputEvent,
    Select: selectEvent,
    DatePicker: datePickerEvent,
  };

  /** 重置排序条件 */
  const resetSortConditions = () => {
    sortConditions.length = 0;
  };

  /** 生成排序条件 */
  const genSortCondition = (field: string, sort: SortEnum) => {
    const sortCondition = { field, sort };
    sortConditions.push(sortCondition);
  };

  /** 生成分页条件 */
  const genPageCondition = (pageIndex: number = 1, pageSize: number = 10, sortConditions: SortCondition[] = []) => {
    pageCondition.pageIndex = pageIndex;
    pageCondition.pageSize = pageSize;
    pageCondition.sortConditions = sortConditions;
  };

  /** 生成 rule */
  const genRule = (field: string, data: any, operate: FilterOperateEnum) => {
    return { field, data, operate };
  };

  /** 重置 rule */
  const resetRule = () => {
    filterRules.length = 0;
  };

  /** 生成 groups */
  const genGroup = (rules: Rule[], operate: FilterOperateEnum) => {
    groups.push({ operate, rules });
  };

  /** 重置 group */
  const resetGroup = () => {
    groups.length = 0;
  };

  /** 生成查询条件组 */
  const genFilterGroup = (formSchema: FormSchema[]) => {
    resetRule();
    resetGroup();
    for (const schema of formSchema) {
      comEventMap[schema.type](schema);
    }
    filterGroup.groups = groups;
    filterGroup.rules = filterRules;
  };

  /** 重置 filterGroup */
  const resetFilterGroup = (formSchema: FormSchema[]) => {
    for (const schema of formSchema) {
      schema.value = null;
    }
    resetRule();
    resetGroup();
    filterGroup.groups = groups;
    filterGroup.rules = filterRules;
  };

  /** 生成查询条件 */
  const genSearchCondition = (filterGroup: FilterGroup, pageCondition: PageCondition) => {
    searchCondition.filterGroup = filterGroup;
    searchCondition.pageCondition = pageCondition;
  };

  /** 重置查询条件 */
  const resetSearchCondition = (formSchema: FormSchema[]) => {
    resetSortConditions();
    genPageCondition();
    resetFilterGroup(formSchema);
  };

  return {
    sortConditions,
    pageCondition,
    filterRules,
    groups,
    filterGroup,
    searchCondition,
    resetSortConditions,
    genSortCondition,
    genPageCondition,
    genFilterGroup,
    genSearchCondition,
    resetRule,
    resetGroup,
    resetSearchCondition,
  };
};
